import { createApp } from './app'
import { getDefaultConfig } from '../config/app_default.cfg'
import { WSS } from './shared/request/websocket'
import httpProxy from 'http-proxy'
import http from 'http'
import cluster, { Worker } from 'cluster'
import cpus from 'os'
import { Vite } from 'koacat'

(async () => {
  let config = getDefaultConfig()
  if (config.ENV === 'local') {
    // @ts-ignore
    config = (await import('../config/app_local.cfg')).getLocalConfig()
  }
  const sharedVite = new Vite({ ...config.VITEX, env: config.ENV === 'production' ? 'production' : 'default' })
  const workers = [] as Array<Worker>

  if (cluster.isPrimary) {

    cluster.on('online', (worker) => {
      workers.push(worker)
      console.log(`Worker-${worker.id} ${worker.process.pid} is online`)
    })

    for (let i = 0; i < config.CPUS; i++) {
      const worker = cluster.fork()
      // workers.push(worker)
    }

    cluster.on('exit', (worker, code, signal) => {
      console.log(`Worker-${worker.id} ${worker.process.pid} died`)
      const newWorker = cluster.fork()
      const index = workers.indexOf(worker)
      workers.splice(index, 1, newWorker)
    })

    const proxy = httpProxy.createProxyServer()
    const proxyServer = http.createServer((req, res) => {
      const targetWorkerIndex = Math.floor(Math.random() * (config.CPUS - 1)) + 1
      const targetWorker = workers[targetWorkerIndex]
      // console.log(targetWorkerId)
      // console.log(targetWorker)
      if (targetWorker) {
        proxy.web(req, res, { target: `http://127.0.0.1:${config.LISTEN_PORT + targetWorker.id}` }) 
      } else {
        res.writeHead(500)
        res.end('Internal Server Error')
      }
    })

    proxyServer.listen(config.LISTEN_PORT) 
    console.log(`Main process - Successfully running in http://127.0.0.1:${config.LISTEN_PORT}`)
  } else {
    config.LISTEN_PORT += cluster.worker!.id
    const app = await createApp(config,sharedVite)
    console.log(`${app.env.toUpperCase()}-${cluster.worker?.id} - Successfully running in http://127.0.0.1:${app.config.LISTEN_PORT}`)
    app.run()
    WSS.createWebSocketServer(app)
  }

})()
  .catch(e => {
    console.error(e)
    process.exit(1)
  })
